function ID = C_createAudioIn(varargin)
%% Setup an audio streamer for a certain set of channels 
% This requires to discover devices, check that channels are not in use
% already
% 
global CG;

%% CHECK FOR LAST SESSION ID
ID = C_getModuleID('ModuleType','AudioIn');

%% PARSE INITIALIZATION ARGUMENTS
P = parsePairs(varargin);
% PARAMETERS
Pars = C_getParametersModule('ModuleType','AudioIn','IDType',ID);
for iP = 1:length(Pars) checkField(P,Pars{iP}.Name,Pars{iP}.Value); end
% OPTIONS
checkField(P,'Start',0);
checkField(P,'Reset',0);

%% CHECK WHETHER CHANNELS ALREADY USED
C_discoverAudio; % attach audio to SG if not done before

%% INITIALIZE AUDIO IF NECESSARY
if P.Reset C_resetAudioIn; end;

%% GET NEW AUDIO SESSION
CG.Sessions.AudioIn.S(ID) = daq.createSession('directsound');
cS = CG.Sessions.AudioIn.S(ID);
cS.IsContinuous = true;
CG.Sessions.AudioIn.Types{ID} = '';

%% SET SAMPLING RATE
Rates = get(cS,'StandardSampleRates');
SR = Rates(Rates==P.SR);
if ~isempty(SR)  cS.Rate = SR; 
else             error(['Specified SR (',num2str(P.SR),') is not available.']); 
end

%% SETUP SESSION
% ADD INPUT CHANNELS
for iC = 1:length(P.Channels)
  cChannel = P.Channels(iC);
  cID = CG.Devices.Audio.(P.Device).Input.DevicesByChannel(cChannel).ID;
  cLocalChannel = CG.Devices.Audio.(P.Device).Input.DevicesByChannel(cChannel).LocalChannel;
  addAudioInputChannel(cS,cID,cLocalChannel);
end

%% SETUP INPUT CALLBACK FUNCTION
ControlSamples = lower(P.SR * P.ControlInterval);
CG.Sessions.AudioIn(ID).ControlSamples = ControlSamples;
cS.NotifyWhenDataAvailableExceeds = ControlSamples;
CG.Sessions.AudioIn(ID).CallbackAvail =  ...
  addlistener(cS,'DataAvailable',@(src,evt)C_callbackAudioIn(src,evt,ID));
CG.Sessions.AudioIn(ID).Name = P.Name;
CG.Sessions.AudioIn(ID).Device = 'Microphone';

%% SETUP FIGURE
% Could this be for Output as well? Probably it would make sense, if it can
% adapt to the number of data packets for both in and out.
CG.Display.AudioIn(ID).State = 0;
CG.Display.AudioIn(ID).FIG = [];
CG.Data.AudioIn(ID) = struct('Data',[],'Time',[]);

C_prepareAudioInDisplay(ID);

%% START AUDIO
if P.Start C_startAudioIn(ID); end
